# 把函数作为对象传入
def f(x):
    return x * x

map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
#[1, 4, 9, 16, 25, 36, 49, 64, 81]

# reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
def sum(x1, x2):
	return x1 + x2
reduce(sum, range(1, 100))

# map 和 reduce 集合完成 str2int 函数
# 也是有白点折腾的感觉，关键是 map 和 reduce 的使用
def str2int(s):
	def fn(x, y):
		return x * 10 + y
	return reduce(fn, map(int, s))
# 简化
def str2int(s):
	return reduce(lambda x, y: x * 10 + y, map(int, s))	


# 排序算法
sorted([36, 5, 12, 9, 21])
# 自定义倒序排列
def cmpNumber(x, y):
    if x < y:
            return 1
    elif x == y:
            return 0
    else:
            return -1

sorted(range(1,20), cmpNumber)
# 忽略大小写的字符串排序
def cmpIgnoreCase(s1, s2):
	l1 = s1.lower()
	l2 = s2.lower()
	if l1 > l2:
		return 1
	elif l1 == l2:
		return 0
	else:
		return -1

sorted(['Good', 'hello', 'Python', 'aaa'], cmpIgnoreCase)


# 函数作为返回值
def lazy_sum(*args):
	def sum():
		ax = 0
		for n in args:
			ax += n
		return ax
	return sum
f = lazy_sum(1, 3, 5, 7, 9)
f()
# f 不执行的时候里面包含了函数和数值，这个是传说中很强大的函数闭包

# 模仿 map() 的功能自制 myMap()
def myMap(fun, list):
	return [fun(n) for n in list]

# 模仿 reduce() 的功能自制 myReduce()
def myReduce(fun, list):
	length = len(list)
	temp = list[0]
	i = 1
	while i < length:
		temp = fun(temp, list[i])
		i += 1
	return temp

# 匿名函数
# 返回值就是一个函数对象
f = lambda x: x * x
f(5)
# 还可以闭包
def build(x, y):
	return lambda: x * y


# 装饰器
def log(func):
	def wrapper(*args, **kw):
		print 'call %s():' % func.__name__
		return func(*args, **kw)
	return wrapper
# 使用方法
@log
def now():
	print '2014-07-20'
>>> now()
# @log 相当于 now = @log(now)
# 多层自定义提示的 decorator
def log(text):
	def decorator(func):
		def wrapper(*args, **kw):
			print '%s %s():' % (text, func.__name__)
			return func(*args, **kw)
		return wrapper
	return decorator

@log('execute')
def now():
	print '2014-07-20'
# 相当于 now = log('execute')(now)
# 此时 now.__name__ 会变成 wrapper，需要用下面的方法来转换
import functools

def log(text):
	def decorator(func):
		@functools.wraps(func)
		def wrapper(*args, **kw):
			print '%s %s():' % (text, func.__name__)
			return func(*args, **kw)
		return wrapper
	return decorator

# 自己的练习
def callPro(call):
	def wrapper(*args, **kw):
		print 'begin call'
		result = call(*args, **kw)
		print 'end call'
		return result
	return wrapper

@callPro
def call():
	print 'calling'

# 偏函数
# 使用偏函数可以省去非默认参数的配置，比如这样
int('12345')
int('ff', 16)
# 可以手写
def int16(x):
	return int(x, 16)
# 上面的 16 也可以写成是 base ＝ 16，可能因为内部在用键值对吧
# 或者用下面的来固定住原函数的部分参数
import functools
int16 = functools.partial(int, base ＝ 16)








